grammar Scribe;

@header {
package com.example.scribe.parser;
}

options {
    language=Java;
}

// Parser rules
program
    : (NEWLINE* statement)* NEWLINE* EOF
    ;

statement
    : variable_decl
    | function_decl
    | expression_stmt
    | import_stmt
    | export_stmt
    | if_stmt
    | while_stmt
    | for_stmt
    | block_stmt
    | return_stmt
    | try_stmt
    ;

variable_decl
    : (LET | CONST) identifier (':' type_annotation)? ('=' expression)? (';' | NEWLINE)?
    ;

function_decl
    : FN identifier? '(' param_list? ')' (':' type_annotation)? block_stmt
    ;

lambda_expr
    : '(' param_list? ')' '=>' (expression | block_stmt)
    ;

param_list
    : param (',' param)*
    ;

param
    : identifier ':' type_annotation
    ;

type_annotation
    : primitive_type // 只允许内置类型，暂时不支持用户自定义类型
    ;

primitive_type
    : 'i8' | 'i16' | 'i32' | 'i64'  // integer types
    | 'f32' | 'f64'                  // floating point types
    | 'bool'                         // boolean type
    ;

expression_stmt
    : expression (';' | NEWLINE)?
    ;

import_stmt
    : IMPORT import_clause (',' import_clause)* (';' | NEWLINE)?
    ;

import_clause
    : (identifier | java_qualified) ('from' STRING)?
    ;

java_qualified
    : identifier ('.' identifier)+
    ;

export_stmt
    : EXPORT (FN function_decl | CONST variable_decl | LET variable_decl | expression_stmt)
    ;

// Control flow statements
if_stmt
    : IF expression block_stmt 
      (ELSE (block_stmt | if_stmt))?
    ;

while_stmt
    : WHILE expression block_stmt
    ;

for_stmt
    : FOR identifier IN expression block_stmt
    ;

block_stmt
    : '{' (NEWLINE* statement)* NEWLINE* '}'
    ;

return_stmt
    : RETURN expression? (';' | NEWLINE)?
    ;

try_stmt
    : TRY block_stmt (CATCH '(' identifier ')' block_stmt)? (FINALLY block_stmt)?
    ;

expression
    : assignment
    ;

assignment
    : conditional ( ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '&=' | '|=' | '^=') assignment )?
    ;

conditional
    : logical_or ( '?' expression ':' expression )?
    | range_expr
    ;

range_expr
    : logical_or '..' logical_or      // exclusive range: 0..10 means 0 to 9
    | logical_or '..=' logical_or     // inclusive range: 0..=10 means 0 to 10
    ;

logical_or
    : logical_and ( '||' logical_and )*
    ;

logical_and
    : equality ( '&&' equality )*
    ;

equality
    : comparison ( ('==' | '!=') comparison )*
    ;

comparison
    : bitwise_or ( ('<' | '>' | '<=' | '>=') bitwise_or )*
    ;

bitwise_or
    : bitwise_xor ( '|' bitwise_xor )*
    ;

bitwise_xor
    : bitwise_and ( '^' bitwise_and )*
    ;

bitwise_and
    : addition ( '&' addition )*
    ;

addition
    : shift ( ('+' | '-') shift )*
    ;

shift
    : multiplication ( ('<<' | '>>' | '>>>') multiplication )*
    ;

multiplication
    : unary ( ('*' | '/' | '%') unary )*
    ;

unary
    : ('!' | '-' | '~') unary
    | call
    ;

call
    : primary ( '(' arg_list? ')' | '.' identifier | '[' expression ']' )*
    ;

arg_list
    : expression (',' expression)*
    ;

primary
    : lambda_expr
    | identifier
    | NUMBER
    | STRING
    | TEMPLATE
    | TRUE
    | FALSE
    | NULL
    | NEW primary
    | '(' expression ')'
    ;

identifier
    : IDENT
    ;

// Lexer rules

LET : 'let';
CONST : 'const';
FN : 'fn';
I8 : 'i8';
I16 : 'i16';
I32 : 'i32';
I64 : 'i64';
F32 : 'f32';
F64 : 'f64';
BOOL : 'bool';
IMPORT : 'import';
EXPORT : 'export';
IF : 'if';
ELSE : 'else';
FOR : 'for';
IN : 'in';
WHILE : 'while';
RETURN : 'return';
TRY : 'try';
CATCH : 'catch';
FINALLY : 'finally';
TRUE : 'true';
FALSE : 'false';
NULL : 'null';
NEW : 'new';

// 数字字面量（带类型后缀支持）
// 数字字面量规则
NUMBER
    : INTEGER           // 整数（无后缀或带整数类型后缀）
    | FLOAT            // 浮点数（无后缀或带浮点类型后缀）
    ;

// 整数规则
fragment INTEGER
    : DIGIT+                   // 无后缀
    | DIGIT+ INTEGER_SUFFIX    // 带类型后缀
    ;

// 浮点数规则
fragment FLOAT
    : DIGIT+ '.' DIGIT+              // 无后缀
    | DIGIT+ '.' DIGIT+ FLOAT_SUFFIX // 带类型后缀
    ;

// 基础组件
fragment DIGIT : [0-9] ;

fragment INTEGER_SUFFIX
    : 'i8' | 'i16' | 'i32' | 'i64'
    ;

fragment FLOAT_SUFFIX
    : 'f32' | 'f64'
    ;
IDENT : [A-Za-z_][A-Za-z0-9_]* ;

STRING
    : '"' ( ~["\\] | '\\' . )* '"'
    | '\'' ( ~['\\] | '\\' . )* '\''
    ;

TEMPLATE : '`' ( ~[`\\] | '\\' . )* '`' ;

LINE_COMMENT : '//' ~[\r\n]* -> skip ;
BLOCK_COMMENT : '/*' .*? '*/' -> skip ;

// Keep NEWLINE separate so we can implement minimal newline-aware rules / optional semicolon logic later.
WS : [ \t]+ -> channel(HIDDEN);

NEWLINE : '\r'? '\n' ;

SEMICOLON : ';' ;

// Operators and punctuation will be matched by literal tokens used in parser rules
